package middleware

import (
	"kstar-gf-api/library/redislock"
	"kstar-gf-api/library/response"

	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/net/ghttp"
	"github.com/gogf/gf/v2/util/gconv"
)

type AuthInfoRes struct {
	ParentId    int    `json:"parentId"`
	OpenId      string `json:"openId"`
	Token       string `json:"token"`
	ParentPhone string `json:"parentPhone"`

	LastStudentInfo *LastStudentInfo `json:"lastStudentInfo" dc:"上一次登录的学生信息"`
}

type LastStudentInfo struct {
	SchoolId    int    `json:"schoolId"    dc:"学校ID"`
	SchoolName  string `json:"schoolName"  dc:"学校名称"`
	StudentId   int    `json:"studentId"   dc:"学生ID"`
	StudentName string `json:"studentName" dc:"学生姓名"`
	ClassId     int    `json:"classId"     dc:"所属班级ID"`
	ClassName   string `json:"className"   dc:"班级名称"`
}

// 校验登录
func MiddlewareLoginHandler(r *ghttp.Request) {

	sessionInfo, _ := r.Session.Data()

	var authInfo *AuthInfoRes
	if err := gconv.Struct(sessionInfo, &authInfo); err != nil {
		response.NotLoginReturn(r)
	}

	if authInfo.ParentId == 0 {
		response.NotLoginReturn(r)
	}

	//设置上下文变量
	r.SetCtxVar("OpenId", authInfo.OpenId)
	r.SetCtxVar("ParentId", authInfo.ParentId)
	r.SetCtxVar("Token", authInfo.Token)
	r.SetCtxVar("ParentPhone", authInfo.ParentPhone)

	// post接口防止重复提交数据，必须等上一次返回后才能调下一次
	if r.Method == "POST" {
		ctx := r.Request.Context()

		// 根据URL+parentId生成唯一的Redis锁key
		urlPath := r.URL.Path
		lockKey := "PostLock:" + urlPath + ":" + gconv.String(authInfo.ParentId)

		// 尝试获取锁，如果获取失败说明重复调用post请求
		lockAcquired := redislock.AcquireLock(ctx, lockKey)
		if !lockAcquired {
			response.InnerErrorReturn(r, gerror.New("post请求调用太频繁"))
		}

		// 确保在请求结束时释放锁
		defer redislock.ReleaseLock(ctx, lockKey)
	}

	r.Middleware.Next()
}

// 校验是否选择学生
func MiddlewareSelectStudentHandler(r *ghttp.Request) {

	sessionInfo, _ := r.Session.Data()

	var authInfo *AuthInfoRes
	if err := gconv.Struct(sessionInfo, &authInfo); err != nil {
		response.NotLoginReturn(r)
	}

	if authInfo.LastStudentInfo == nil || authInfo.LastStudentInfo.StudentId == 0 {
		response.NotLoginReturn(r)
	}

	//设置上下文变量
	r.SetCtxVar("StudentId", authInfo.LastStudentInfo.StudentId)
	r.SetCtxVar("StudentName", authInfo.LastStudentInfo.StudentName)
	r.SetCtxVar("SchoolId", authInfo.LastStudentInfo.SchoolId)
	r.SetCtxVar("SchoolName", authInfo.LastStudentInfo.SchoolName)

	r.Middleware.Next()
}
